const ZOHO = window.ZOHO;
// const API_URL = 'https://www.zohoapis.com.cn';

export async function getCrmRecordFromSql(sql) {
  let req_data = {
    parameters: {
      select_query: `${sql}`,
    },
    headers: {},
    method: "POST",
    url: `https://www.zohoapis.com.cn/crm/v6/coql`,
    param_type: 2,
  };
  let contact = await ZOHO.CRM.CONNECTION.invoke("crm", req_data);
  console.log("contact", contact);
  return contact.details.statusMessage.data;
}
export async function getglobal_picklists() {
  let req_data = {
    headers: {},
    method: "GET",
    url: `https://www.zohoapis.com.cn/crm/v7/settings/global_picklists`,
    param_type: 2,
  };
  let contact = await ZOHO.CRM.CONNECTION.invoke("crm", req_data);
  console.log("contact", contact);
  return contact.details.statusMessage.data;
}
export async function getCrmRecordFromSqlReturnAll(sql) {
  let req_data = {
    parameters: {
      select_query: `${sql}`,
    },
    headers: {},
    method: "POST",
    url: `https://www.zohoapis.com.cn/crm/v6/coql`,
    param_type: 2,
  };
  let contact = await ZOHO.CRM.CONNECTION.invoke("crm", req_data);
  return contact;
}

export async function getCrmvariables(variable_id) {
  let req_data = {
    headers: {},
    method: "GET",
    url: `https://www.zohoapis.com.cn/crm/v6/settings/variables/${variable_id}`,
    param_type: 2,
  };
  let contact = await ZOHO.CRM.CONNECTION.invoke("crm", req_data);
  return contact;
}

export async function usersql(sql) {
  let config = {
    select_query: sql,
  };
  let result = await window.ZOHO.CRM.API.coql(config);

  if (Array.isArray(result.data)) {
    return result.data;
  } else {
    return [];
  }
}

export async function usersqlalldata(sql, maxLimit = 2000) {
  const allData = [];
  const pageSize = 100; // 每页查询条数
  let offset = 0;

  while (true) {
    try {
      // 构造带偏移量的查询
      const query = `${sql} LIMIT ${pageSize} OFFSET ${offset}`;
      const config = { select_query: query };
      const result = await window.ZOHO.CRM.API.coql(config);

      // console.log("Result:", result);

      // 验证结果有效性
      if (result && Array.isArray(result.data)) {
        allData.push(...result.data); // 合并数据

        // 检查是否超出最大限制
        if (allData.length >= maxLimit) {
          // console.log("达到数据上限，停止查询");
          break;
        }
      } else {
        // console.warn("无效的查询结果，停止查询");
        break;
      }

      // 检查分页终止条件
      if (
        result.data.length < pageSize || // 当前页数据不足
        !result.info.more_records // 没有更多记录
      ) {
        // console.log("数据查询完成");
        break;
      }

      // 更新偏移量，查询下一页
      offset += pageSize;
    } catch (error) {
      console.error("查询过程中发生错误:", error);
      break; // 如果发生异常，退出循环
    }
  }

  // 返回数据，限制在 maxLimit 条
  return allData;
}

export async function getCrmRecordFromSqlMoreLimit(sql) {
  let allRecords = []; // 存储所有记录的数组
  let start = 0; // 起始位置
  const limit = 2000; // 每次查询的数据量
  let moreRecords = true; // 是否还有更多记录的标志

  while (moreRecords) {
    // 构造请求数据
    let req_data = {
      parameters: {
        select_query: `${sql} LIMIT ${start}, ${limit}`,
      },
      headers: {},
      method: "POST",
      url: `https://www.zohoapis.com.cn/crm/v6/coql`,
      param_type: 2,
    };
    // 调用 Zoho CRM API 获取数据
    let contact = await ZOHO.CRM.CONNECTION.invoke("crm", req_data);
    // console.log("contact", contact);
    // 检查是否成功获取到数据
    if (contact?.details?.statusMessage?.data) {
      // 将当前页的数据添加到 allRecords 数组中
      allRecords.push(...contact.details.statusMessage.data);

      // 检查是否有更多记录
      moreRecords = contact?.details?.statusMessage?.info.more_records;

      // 如果有更多记录，则更新起始位置继续查询下一批数据
      if (moreRecords) {
        start += limit;
      }
    } else {
      moreRecords = false; // 如果没有获取到数据，则停止查询
    }
  }

  return allRecords;
}

export async function getCrmRecordFromSqlAllDataByIn(sqlstr, arrar) {
  const chunkArray = (arr, chunkSize) => {
    const chunks = [];
    for (let i = 0; i < arr.length; i += chunkSize) {
      chunks.push(arr.slice(i, i + chunkSize));
    }
    return chunks;
  };

  const chunks = chunkArray(arrar, 50);
  const results = [];

  for (const chunk of chunks) {
    const strs = chunk.map((item) => `'${item}'`).join(",");
    const sql = `${sqlstr} in (${strs})`;

    let req_data = {
      parameters: {
        select_query: `${sql} limit 2000`,
      },
      headers: {},
      method: "POST",
      url: `https://www.zohoapis.com.cn/crm/v6/coql`,
      param_type: 2,
    };

    try {
      let contact = await ZOHO.CRM.CONNECTION.invoke("crm", req_data);
      console.log("contact", contact);

      if (
        contact.details.status === "success" &&
        contact.details.statusMessage &&
        contact.details.statusMessage.data
      ) {
        results.push(...contact.details.statusMessage.data);
      } else {
        console.warn(`No data returned for chunk: ${JSON.stringify(chunk)}`);
      }
    } catch (error) {
      console.error(
        `Error fetching data for chunk: ${JSON.stringify(chunk)}`,
        error
      );
    }
  }

  return results;
}

export async function putdata(moduleName, jsondata) {
  let req_data = {
    parameters: jsondata,
    headers: {},
    method: "PUT",
    url: `https://www.zohoapis.com.cn/crm/v6/${moduleName}`,
    param_type: 2,
  };
  let contact = await ZOHO.CRM.CONNECTION.invoke("crm", req_data);
  return contact;
}
export async function upsertdata(moduleName, jsondata) {
  let req_data = {
    parameters: jsondata,
    headers: {},
    method: "POST",
    url: `https://www.zohoapis.com.cn/crm/v7/${moduleName}`,
    param_type: 2,
  };
  let contact = await ZOHO.CRM.CONNECTION.invoke("crm", req_data);
  return contact;
}
export async function getCrmRecordById(moduleName, id) {
  let req_data = {
    parameters: {},
    headers: {},
    method: "GET",
    url: `https://www.zohoapis.com.cn/crm/v6/${moduleName}/${id}`,
    param_type: 2,
  };
  let contact = await ZOHO.CRM.CONNECTION.invoke("crm", req_data);
  // console.log("contact", contact);
  return contact.details.statusMessage.data[0];
}
//https://crm.zoho.com.cn/crm/v2.2/settings/global_picklists?
export async function getCrmSettingsRecordById(moduleName, id) {
  let req_data = {
    parameters: {},
    headers: {},
    method: "GET",
    url: `https://www.zohoapis.com.cn/crm/v6/settings/${moduleName}/${id}?include=used_in_modules&include_inner_details=used_in_modules.plural_label`,
    param_type: 2,
  };
  console.log(req_data);
  let contact = await ZOHO.CRM.CONNECTION.invoke("crm", req_data);
  console.log("contact", contact);
  return contact;
}

export async function getCrmMailmergeById(moduleName, dataid, templateid) {
  let req_data = {
    method: "GET",
    headers: { "Content-Type": "application/pdf; charset=utf-8" },
    url: `https://zohoapis.com.cn/crm/v2/${moduleName}/${dataid}/actions/print_preview?type=mailmerge&template_id=${templateid}`,
    param_type: 1,
  };
  let response = await ZOHO.CRM.CONNECTION.invoke("crm", req_data);
  return response;
}
export async function getCrmMailmergeList(moduleName) {
  let req_data = {
    method: "GET",
    url: `https://www.zohoapis.com.cn/crm/v2/settings/templates?type=mailmerge&module=${moduleName}`,
    param_type: 2,
  };
  let response = await ZOHO.CRM.CONNECTION.invoke("crm", req_data);
  return response;
}

export async function getCrmFile(fileid) {
  let req_data = {
    method: "GET",
    headers: { "Content-Type": "application/pdf; charset=utf-8" },
    url: `https://www.zohoapis.com.cn/crm/v5/files?id=${fileid}`,
    param_type: 2,
  };
  let response = await ZOHO.CRM.CONNECTION.invoke("crm", req_data);
  console.log(typeof response);
  return response;
}
export function isBlank(str) {
  return str === undefined || str === null || str === "";
}

export function groupBy(array, keys, groupName) {
  return Object.entries(
    array.reduce((acc, item) => {
      const groupKey = keys
        .map((key) =>
          key.split(".").reduce((obj, prop) => obj && obj[prop], item)
        )
        .join("_");

      if (!acc[groupKey]) {
        acc[groupKey] = { [groupName]: [] };
      }
      acc[groupKey][groupName].push(item);
      return acc;
    }, {})
  ).map(([key, value]) => ({
    [groupName]: value[groupName],
  }));
}

export function groupByAndSum(data, groupByFields, sumFields) {
  return data.map((declaration) => {
    const grouped = declaration.DeclarationSubfrom.reduce((result, current) => {
      const groupKey = groupByFields.map((field) => current[field]).join("|");
      if (!result[groupKey]) {
        result[groupKey] = {};
        groupByFields.forEach((field) => {
          result[groupKey][field] = current[field];
        });
        sumFields.forEach((field) => {
          result[groupKey][field] = current[field] || 0;
        });
      } else {
        sumFields.forEach((field) => {
          result[groupKey][field] += current[field] || 0;
        });
      }
      return result;
    }, {});

    const DeclarationSubfrom = Object.values(grouped);

    // 计算总和字段
    const totalSum = {};
    sumFields.forEach((field) => {
      totalSum[field + "_sum"] = DeclarationSubfrom.reduce(
        (sum, item) => sum + item[field],
        0
      );
    });

    return {
      DeclarationSubfrom,
      ...totalSum,
    };
  });
}

export function numberToEnglish(num) {
  const ones = [
    "",
    "One",
    "Two",
    "Three",
    "Four",
    "Five",
    "Six",
    "Seven",
    "Eight",
    "Nine",
  ];
  const tens = [
    "",
    "",
    "Twenty",
    "Thirty",
    "Forty",
    "Fifty",
    "Sixty",
    "Seventy",
    "Eighty",
    "Ninety",
  ];
  const teens = [
    "Ten",
    "Eleven",
    "Twelve",
    "Thirteen",
    "Fourteen",
    "Fifteen",
    "Sixteen",
    "Seventeen",
    "Eighteen",
    "Nineteen",
  ];

  function convertLessThanOneThousand(n) {
    if (n === 0) return "";
    if (n < 10) return ones[n];
    if (n < 20) return teens[n - 10];
    if (n < 100)
      return (
        tens[Math.floor(n / 10)] + (n % 10 !== 0 ? " " + ones[n % 10] : "")
      );
    return (
      ones[Math.floor(n / 100)] +
      " Hundred" +
      (n % 100 !== 0 ? " and " + convertLessThanOneThousand(n % 100) : "")
    );
  }

  if (num === 0) return "ZERO";

  let result = "";
  let billions = Math.floor(num / 1000000000);
  let millions = Math.floor((num % 1000000000) / 1000000);
  let thousands = Math.floor((num % 1000000) / 1000);
  let remainder = num % 1000;

  // 处理整数部分
  if (billions > 0)
    result += convertLessThanOneThousand(billions) + " Billion ";
  if (millions > 0)
    result += convertLessThanOneThousand(millions) + " Million ";
  if (thousands > 0)
    result += convertLessThanOneThousand(thousands) + " Thousand ";
  if (remainder > 0) result += convertLessThanOneThousand(remainder);

  // 处理小数部分
  let cents = Math.round((num % 1) * 100); // 获取小数部分的两位数字
  if (cents > 0) {
    result += " and " + convertLessThanOneThousand(cents) + " Cents";
  }

  return result.trim().toUpperCase() + " ONLY";
}

export function formatDateToUpper(dateStr) {
  if (!dateStr) {
    return "";
  }

  const months = [
    "JAN",
    "FEB",
    "MAR",
    "APR",
    "MAY",
    "JUN",
    "JUL",
    "AUG",
    "SEP",
    "OCT",
    "NOV",
    "DEC",
  ];

  const dateParts = dateStr.split("-");
  if (dateParts.length !== 3) {
    return "";
  }

  const year = dateParts[0];
  const month = parseInt(dateParts[1], 10) - 1;
  const day = dateParts[2];

  if (isNaN(month) || isNaN(day) || isNaN(year)) {
    return "";
  }

  const monthName = months[month];
  return `${monthName}.${day},${year}`;
}

export function parseWString(input) {
  const result = [];
  try {
    const pattern = /W\d{4}(?:\/\d+)+|W\d{4}/g;

    if (/[^\w/]/.test(input)) return [];

    input.match(pattern)?.forEach((match) => {
      if (match.includes("/")) {
        const base = match.match(/^W\d{4}/)[0]; // 提取WXXXX部分
        const baseNumber = parseInt(base.substring(1)); // 提取基数
        const suffixes = match.substring(5).split("/"); // 提取斜杠后的所有数字

        result.push(base); // 添加基数部分
        suffixes.forEach((suffix, index) => {
          const num = parseInt(suffix);
          if (!isNaN(num)) {
            result.push(`W${num}`);
          } else {
            result.push(`W${baseNumber + index + 1}`); // 基数部分已添加，所以index需要+1
          }
        });
      } else {
        result.push(match);
      }
    });

    return result.length ? result : [];
  } catch {
    return [];
  }
}

export function findMostFrequentValue(array, key) {
  const valueCount = array.reduce((acc, obj) => {
    const value = obj[key];
    acc[value] = (acc[value] || 0) + 1;
    return acc;
  }, {});

  return Object.keys(valueCount).reduce((mostFrequent, current) => {
    return valueCount[current] > valueCount[mostFrequent]
      ? current
      : mostFrequent;
  });
}

export async function getFileContentAsString(dataid) {
  try {
    // 使用 getCrmRecordById 获取记录信息
    let changeallinfo = await getCrmRecordById("ChangeAll", dataid);
    console.log("changeallinfo", changeallinfo);

    // 提取 fileid

    if (changeallinfo && changeallinfo?.File.length > 0) {
      let fileid = changeallinfo?.File[0]?.File_Id__s;
      let lastrecorddataconfig = {
        id: fileid,
      };

      // 获取文件 Blob
      let lastrecordblob = await window.ZOHO.CRM.API.getFile(
        lastrecorddataconfig
      );

      // 创建一个 Promise 来处理 Blob 到字符串的转换
      let blobToString = new Promise((resolve, reject) => {
        let reader = new FileReader();

        reader.onloadend = function () {
          resolve(reader.result); // 成功时返回字符串
        };

        reader.onerror = function () {
          reject(reader.error); // 读取错误时触发
        };

        reader.readAsText(lastrecordblob); // 将 Blob 读取为文本
      });

      // 返回转换后的字符串
      return await blobToString;
    }
    return ""; // 如果 fileid 不存在，返回空字符串
  } catch (error) {
    console.error("Error fetching or reading file:", error);
    return ""; // 出错时返回空字符串
  }
}
